/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.basics.manager;

import java.io.InputStream;
import java.io.OutputStream;

import com.genia.toolbox.basics.bean.InputStreamFactory;
import com.genia.toolbox.basics.bean.StreamProgressListener;
import com.genia.toolbox.basics.exception.technical.TechnicalIOException;

/**
 * this is an utility class that handle Streams.
 */
public interface StreamManager
{

  /**
   * Copy the content of an {@link InputStream} to an {@link OutputStream}.
   * 
   * @param input
   *          the {@link InputStream}
   * @param output
   *          the {@link OutputStream}
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public void copyStream(InputStream input, OutputStream output)
      throws TechnicalIOException;



  /**
   * Copy at most <code>byteCount</code> (<code>-1</code> means no limit)
   * of content from an {@link InputStream} to an {@link OutputStream}.
   * 
   * @param input
   *          the {@link InputStream}
   * @param output
   *          the {@link OutputStream}
   * @param byteCount
   *          number of byte to copie (<code>-1</code> mean no limit)
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public void copyStream(InputStream input, OutputStream output, long byteCount)
      throws TechnicalIOException;



  /**
   * Return the content of the input as in byte array.
   * 
   * @param input
   *          the {@link InputStream}
   * @return a byte array containing the content of the input
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public byte[] getBytes(InputStream input)
      throws TechnicalIOException;



  /**
   * Copy the content of an {@link InputStream} to an {@link OutputStream}.
   * 
   * @param input
   *          the {@link InputStream}
   * @param output
   *          the {@link OutputStream}
   * @param progressListener
   *          the {@link StreamProgressListener} to report to, it must not be
   *          <code>null</code>
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public void copyStream(InputStream input, OutputStream output, StreamProgressListener progressListener)
      throws TechnicalIOException;



  /**
   * Copy at most <code>byteCount</code> (<code>-1</code> means no limit)
   * of content from an {@link InputStream} to an {@link OutputStream}.
   * 
   * @param input
   *          the {@link InputStream}
   * @param output
   *          the {@link OutputStream}
   * @param byteCount
   *          number of byte to copie (<code>-1</code> mean no limit)
   * @param progressListener
   *          the {@link StreamProgressListener} to report to, it must not be
   *          <code>null</code>
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public void copyStream(InputStream input, OutputStream output, long byteCount, StreamProgressListener progressListener)
      throws TechnicalIOException;



  /**
   * Return the content of the input as in byte array.
   * 
   * @param input
   *          the {@link InputStream}
   * @return a byte array containing the content of the input
   * @param progressListener
   *          the {@link StreamProgressListener} to report to, it must not be
   *          <code>null</code>
   * @throws TechnicalIOException
   *           if an Input/Output error occurs
   */
  public byte[] getBytes(InputStream input, StreamProgressListener progressListener)
      throws TechnicalIOException;



  /**
   * returns an {@link InputStreamFactory} that generates clone of the given
   * {@link InputStream}. This method use the {@link InputStream} given in
   * parameter.
   * 
   * @param inputStream
   *          the {@link InputStream} to clone
   * @return an {@link InputStreamFactory} that generate clones of the
   *         {@link InputStream} in parameter
   * @throws TechnicalIOException
   *           when an error occured
   */
  public abstract InputStreamFactory cloneInputStream(InputStream inputStream)
      throws TechnicalIOException;



  /**
   * returns the charset of the given {@link InputStream}. The rules is the
   * following: if no byte has a value greater than 127, the charset is ASCII,
   * otherwise if the stream is a correct UTF8 stream, UTF8 is returned.
   * Finally, ISO-8859-1 is returned.
   * 
   * @param inputStream
   *          the {@link InputStream} to check
   * @return the charset of the given {@link InputStream}
   * @throws TechnicalIOException
   *           when an error occured
   */
  public abstract String getCharset(InputStream inputStream)
      throws TechnicalIOException;



  /**
   * returns the {@link InputStream} that is the content of the file at the
   * given path in the zip that is represented by the {@link InputStream} given
   * in parameter.
   * 
   * @param zipInputStream
   *          the {@link InputStream} containing the Zip to search
   * @param filePath
   *          the path of the file to extract
   * @return the {@link InputStream} that is the content of the file at the
   *         given path in the zip that is represented by the
   *         {@link InputStream} given in parameter, or <code>null</code> if
   *         either the file is not a Zip file, or the given file does not exist
   *         in the Zip
   * @throws TechnicalIOException
   *           if an error occured
   */
  public abstract InputStream getInputStreamFromZip(InputStream zipInputStream, String filePath)
      throws TechnicalIOException;
}
